package com.lucene.handle;
import com.google.gson.JsonObject;
import com.lucene.model.Environment;
import com.lucene.model.GroupMessage;
import com.lucene.model.Project;
import com.lucene.model.UserMessage;
import com.lucene.service.ComputeService;
import com.lucene.service.LuceneService;
import com.lucene.utils.Aes;
import com.lucene.utils.Md5;
import com.lucene.utils.Utils;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static com.lucene.service.WechatService.JSON;

/**
 * Created by zhangzhen on 09/10/2017.
 */
public class TulingMessageHandler extends AbstractMessageHandler{

    private static final Logger log = LoggerFactory.getLogger(SampleMessageHandler.class);

    private LuceneService luceneService;
    private ComputeService computeService;


    private String baseUrl = "http://www.tuling123.com/openapi/api";
    private boolean useTulingRobot = false;
    private boolean directseTulingRobot = false;

    private String apiKey;
    private String apiSecret;
    private String w2vPath;
    private String recordPath;

    public TulingMessageHandler(Environment environment) throws IOException{
        this.apiKey = environment.get("tuling.api_key");
        this.apiSecret = environment.get("tuling.api_secret");
        this.w2vPath = environment.get("w2v.path");
        this.recordPath = environment.get("record.path");
        luceneService = new LuceneService();
        computeService = new ComputeService(this.w2vPath);
    }

    @Override
    public void userMessage(UserMessage userMessage) {
        if (null == userMessage) {
            return;
        }
        String text = userMessage.getText();
        log.info("[*] 收到消息: {}",text);
        JsonObject raw_msg = userMessage.getRawMsg();
        String toUid = raw_msg.get("FromUserName").getAsString();
        if ("open".equals(text) || "auto".equals(text) || "开启".equals(text)){
            useTulingRobot = true;
            userMessage.sendText("启用图灵机器人", toUid);
            return;
        }else if ("close".equals(text) || "shutdown".equals(text) || "退下".equals(text) || "闭嘴".equals(text) ){
            useTulingRobot = false;
            userMessage.sendText("已停止使用图灵机器人", toUid);
            return;
        }
        if (useTulingRobot){
            String result = getResult(text);
            userMessage.sendText(result, toUid);
        }
    }

    @Override
    public void groupMessage(GroupMessage groupMessage){
        String text = groupMessage.getText();
        log.info("[*] 群{}-消息:  {}",groupMessage.getGroupId(), text);
//        if (Utils.isNotBlank(text)) {
//            String result = getResult(groupMessage.getText());
//            groupMessage.sendText(result, groupMessage.getGroupId());
//        }
        if (Utils.containTargetGN(groupMessage.getGroup_name())){
            log.info("[*] 对话存档--  --.");
            //目标群 并且 @litemind 进行自动回复
            if (Utils.isNotBlank(text))
                try {
                    Utils.saveFile(this.recordPath,(groupMessage.getGroup_name()+"#"+text+"\n").getBytes("UTF8"));
                }catch (UnsupportedEncodingException e){
                    e.printStackTrace();
                }
            if (groupMessage.isAt() && Utils.isNotBlank(text)){
                groupMessage.sendText("自动回复调用Lucene 检索接口", groupMessage.getGroupId());
                String query = groupMessage.getText().replaceAll("@.*\\u2005","");
                log.info("[*] search lucene {}",query);
                List<Project> rs = luceneService.searchProject(query);
                if (rs.size()>0){
                    for (Project p: rs) {
                        groupMessage.sendText("问题描述:"+p.getDescription()+"\n解决方案:"+p.getScheme(),groupMessage.getGroupId());
                    }
                }else {
                    groupMessage.sendText("没有检索到任何信息",groupMessage.getGroupId());
                }
            }
        }else if (Utils.containDirectGN(groupMessage.getGroup_name()) && Utils.isNotBlank(text)){
            //使用 Tuling 接口
            log.info("[*] 直接回复消息 {}",text);
            if ("close".equals(text)){
                directseTulingRobot = false;
            }else if ("open".equals(text)){
                directseTulingRobot = true;
            }
            // Utils.saveRecord("record/record.txt",groupMessage.getGroup_name()+"#"+text+"\n");
            if (directseTulingRobot && !"open".equals(text)){
                groupMessage.sendText(getResult(text),groupMessage.getGroupId());
            }
        }else if (Utils.containLeiSureGN(groupMessage.getGroup_name()) && groupMessage.isAt()){
            groupMessage.sendText(getResult(text),groupMessage.getGroupId());
        }
    }

    OkHttpClient okHttpClient = new OkHttpClient.Builder()
            .connectTimeout(10, TimeUnit.SECONDS)
            .readTimeout(30, TimeUnit.SECONDS)
            .build();

    private String getResult(String question) {

        Map<String, Object> data = new HashMap<String, Object>(2);
        data.put("key", apiKey);
        data.put("info", question);

        //获取时间戳
        String timestamp = String.valueOf(System.currentTimeMillis());
        //生成密钥
        String keyParam = apiSecret + timestamp + apiKey;
        String key = Md5.MD5(keyParam);

        //加密
        Aes mc = new Aes(key);
        String dataStr = mc.encrypt(Utils.toJson(data));

        //封装请求参数
        Map<String, Object> json = new HashMap<String, Object>(3);
        json.put("key", apiKey);
        json.put("timestamp", timestamp);
        json.put("data", dataStr);

        RequestBody requestBody = RequestBody.create(JSON, Utils.toJson(json));
        Request request = new Request.Builder()
                .url(baseUrl)
                .post(requestBody)
                .build();

        try {
            Response response = okHttpClient.newCall(request).execute();
            TulingRet tulingRet = Utils.fromJson(response.body().string(), TulingRet.class);
            if (tulingRet.code == 100000) {
                return tulingRet.text;
            }
        } catch (Exception e) {
            return null;
        }
        return null;
    }

    class TulingRet {
        int code;
        String text;

    }
}
